package com.gopay.bis.manager.bank.ebank;

import java.util.Date;
import java.util.Map;

import javax.annotation.Resource;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.citic.ebank.pay.CiticB2cMessage;
import com.gopay.common.domain.bank.citic.ebank.query.req.CiticB2cStreamReq;
import com.gopay.common.domain.bank.citic.ebank.query.res.data.CiticB2cStreamDataRes;
import com.gopay.common.domain.bank.citic.ebank.verify.CiticB2cStreamVerify;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.bank.BankManagerRemoteService;
import com.gopay.remote.bank.businesses.BankService;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * @CiticB2cManager.java
 * @author wanggang
 * @2013-12-12 下午1:48:34 www.gopay.com.cn Inc.All rights reserved.
 */
public class CiticB2cManager implements BankManagerRemoteService {

	@Resource(name = "citicConfig")
	private Map<String, String> citicConfig;
	
	@Resource(name = "citicB2cBankServiceClient")
	private BankService citicB2cBankServiceClient;
	
	@Resource(name = "citicB2cBankServiceClientHna")
	private BankService citicB2cBankServiceClientHna;
	
	private final static String XML_HEADER = "<?xml version=\"1.0\" encoding=\"GB2312\" ?>";

	@Override
	public Object sign(BaseMessage msg) throws GopayException {
		CiticB2cMessage message = (CiticB2cMessage) msg;
		
		// 订单支持的支付卡种。00：借记卡和信用卡01：仅借记卡02：仅信用卡
        message.setSupptCardType("00");
        if (!message.isSupportCredit()) {
            message.setSupptCardType("01");
        }
		message.setBankUrl(message.getPayUrl());
		message.setE3rdPayNo(message.getMerID());
		message.setOrderMode(citicConfig.get("CITIC.B2C.ORDERMODE"));
		message.setCurrId(citicConfig.get("CITIC.B2C.CURRID"));
		message.setNotifyMode(citicConfig.get("CITIC.B2C.NOTIFYMODE"));
		message.setNotfyUrl(message.getPayRuturnUrl());
		message.setRiskLevel(citicConfig.get("CITIC.B2C.RISKLEVEL"));
		message.setNotifyScope(citicConfig.get("CITIC.B2C.NOTIFYSCOPE"));
		message.setReferer(citicConfig.get("CITIC.B2C.REFERER"));
		message.setMerberId(citicConfig.get("CITIC.B2C.MEMBERID"));
		message.setMemo(citicConfig.get("CITIC.B2C.MEMO"));
		message.setTtl(citicConfig.get("CITIC.B2C.TTL"));
		Date date = DateUtils.strToDate(message.getOrderDate());
		message.setCiticOrderId(message.getOrderId());
		message.setCiticAmount(message.getAmount().toString());
		message.setCiticOrderDate(DateUtils.format(date, "yyyy-MM-dd"));
		message.setCiticOrderTime(DateUtils.format(date, "HH:mm:ss"));
		message.setIsSafeInf(citicConfig.get("CITIC.B2C.ISSAFEINF"));
		message.setPlainMessage(buildPlain(message));
		BankLogUtils.printB2CManagerSignSendLog(message);
		String signStr;
		if(message.isHna()){
			signStr = (String) citicB2cBankServiceClientHna.sign(message);
	    }else{
	    	signStr = (String) citicB2cBankServiceClient.sign(message);
	    }
		message.setSignMessage(signStr);
		BankLogUtils.printB2CManagerSignReturnLog(message);
		return message;
	}

	@Override
	public Object verify(BaseMessage baseMessage) throws GopayException {
		CiticB2cMessage message = (CiticB2cMessage) baseMessage;
		CiticB2cStreamVerify stream = new CiticB2cStreamVerify();
		String plain;
		if(message.isHna()){
			plain = (String) citicB2cBankServiceClientHna.verify(message);
	    }else{
	    	plain = (String) citicB2cBankServiceClient.verify(message);
	    }
		XStream xs = new XStream(new DomDriver());
		xs.autodetectAnnotations(true);
		xs.toXML(stream);
		stream = (CiticB2cStreamVerify) xs.fromXML(plain, stream);
		return stream;
	}

	@Override
	public Object query(Object baseMessage) throws GopayException {
		CiticB2cMessage message = (CiticB2cMessage) baseMessage;
		CiticB2cStreamReq req = new CiticB2cStreamReq();
		req.setPayNo(citicConfig.get("CITIC.B2C.E3RDPAYNO"));
		req.setOrderNo(message.getOrderId());
		req.setLocalTime(DateUtils.getCurrDate("yyyyMMddHHmmss"));
		String plain = buildPlain(req);
		message.setPlainMessage(plain);
		BankLogUtils.printB2CManagerQuerySendLog(message, req);
		CiticB2cStreamDataRes res;
		if(message.isHna()){
			res = (CiticB2cStreamDataRes) citicB2cBankServiceClientHna.query(message);
	    }else{
	    	res = (CiticB2cStreamDataRes) citicB2cBankServiceClient.query(message);
	    }
		res.setOutStlmCd(BankConstants.BANK_LOGO_CITIC);
		BankLogUtils.printB2CManagerQueryReturnLog(res);
		return res;
	}

	/**
	 * 构建明文信息
	 * 
	 * @param message
	 * @return
	 */
	private String buildPlain(Object message) {
		XStream xs = new XStream(new DomDriver());
		xs.autodetectAnnotations(true);
		String plain = xs.toXML(message);
		StringBuffer xml = new StringBuffer(XML_HEADER);
		xml.append(plain);
		String fullXml = xml.toString();
		fullXml = fullXml.replaceAll("\n", "").replaceAll("\r", "");
		return fullXml;
	}

	@Override
	public Object dayend(BaseMessage base) throws GopayException, Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object refund(BaseMessage base) throws GopayException {
		// TODO Auto-generated method stub
		return null;
	}

}
